package com.timothy.shiro;

import java.util.Set;

import javax.annotation.PostConstruct;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.timothy.business.service.UserDaoService;
import com.timothy.business.service.UserService;
import com.timothy.dao.entity.IdeaUser;
import com.timothy.remote.core.UserEntity;

@Service
public class ServerShiroRealm extends AuthorizingRealm {

	@Autowired
	private ServerShiroProperties shiroProperties;
	@Autowired
	private UserDaoService userDaoService;
	@Autowired
	private UserService userService;

	@PostConstruct
	public void realmInit() {
		this.setAuthorizationCacheName(shiroProperties.getRedisAuthCacheName());
	}

	/**
	 * 授权
	 * @param principals
	 * @return
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		UserEntity user = (UserEntity) SecurityUtils.getSubject().getPrincipal();
		// 用户权限列表
		Set<String> permsSet = userService.getUserPermissionsByName(user.getPhone());
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.setStringPermissions(permsSet);
		return info;
	}

	/**
	 * 认证
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String phone = (String) token.getPrincipal();
		String password = new String((char[]) token.getCredentials());
		if (phone == null || password == null) {
			// 用户名错误
			throw new UnknownAccountException();
		}
		IdeaUser user = userDaoService.getUserByPhone(phone);
		if (user == null) {
			// 用户名错误
			throw new UnknownAccountException();
		} else if (!password.equals(user.getPassword())) {
			// 密码错误
			throw new UnknownAccountException();
		}

		UserEntity userInfo = new UserEntity();
		userInfo.setPhone(phone);
		userInfo.setNickname(user.getNickname());
		userInfo.setUserId(user.getId());
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(userInfo, user.getPassword(),
				getName());
		return authenticationInfo;
	}
}
